/* Includes ------------------------------------------------------------------*/
#include "SystemTick.h"
#include "UART.h"
#include "Led.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define LED_PRESCALE    100

#define SW_DEBOUCE          1000
#define SW_ACTIVE_DEBOUCE   100

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
bool s_Led_IntFlag = FALSE;
u8   s_Led_PrescaleCnt = 0;

eBeepType s_BeepMode = BEEP_IDLE;
u8  s_BeepProcess = 0;
u16 s_BeepCntDown;
#define BEEP_ON     GPIO_WriteHigh(BEEP_PORT, BEEP_PINS)
#define BEEP_OFF    GPIO_WriteLow(BEEP_PORT, BEEP_PINS)

u8      s_OnOffStatus = 0x00;
bool    OnBitOld;
u16     s_OnBitCnt = 0;
bool    OffBitOld;
u16     s_OffBitCnt = 0;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void Led_BeepProcess(void);
/* Public functions ----------------------------------------------------------*/

void Led_TimerInterrupt(void)
{
    if (LED_PRESCALE <= ++s_Led_PrescaleCnt)
    {
        s_Led_PrescaleCnt = 0;
        s_Led_IntFlag = TRUE;
    }
    Led_BeepProcess();
    s_OnBitCnt++;
    s_OffBitCnt++;
}


void Led_Init(void)
{
    // Initialize I/Os in Output Mode
    GPIO_Init(LED_PORT, LED_PINS, GPIO_MODE_OUT_PP_HIGH_SLOW);
    GPIO_Init(BEEP_PORT, BEEP_PINS, GPIO_MODE_OUT_PP_HIGH_SLOW);

    GPIO_Init(SW_ON_PORT, SW_ON_PINS, GPIO_MODE_IN_PU_NO_IT);
    GPIO_Init(SW_OFF_PORT, SW_OFF_PINS, GPIO_MODE_IN_PU_NO_IT);
    
    Led_SetLed(TRUE);
    BEEP_OFF;
    Led_SetBeep(BEEP_IDLE);
    
    OnBitOld = ( (SW_ON_PORT->IDR & SW_ON_PINS) == 0 )? TRUE: FALSE;
    OffBitOld = ( (SW_OFF_PORT->IDR & SW_OFF_PINS) == 0 )? TRUE: FALSE;

    SysTick_Registration(&Led_TimerInterrupt);
}


void Led_SetLed(bool iOn)
{
    if (TRUE == iOn)
    {
        GPIO_WriteHigh(LED_PORT, LED_PINS);
    }
    else
    {
        GPIO_WriteLow(LED_PORT, LED_PINS);
    }
}
  

void Led_InvLed(void)
{
    if ( RESET == GPIO_ReadInputPin(LED_PORT, LED_PINS) )
    {
        GPIO_WriteHigh(LED_PORT, LED_PINS);
    }
    else
    {
        GPIO_WriteLow(LED_PORT, LED_PINS);
    }
}


void Led_SetBeep(eBeepType iMode)
{
    if (iMode == s_BeepMode) return;
    s_BeepMode = iMode;
    s_BeepProcess = 0;
    s_BeepCntDown = 0;
}


void Led_BeepProcess(void)
{
    switch (s_BeepMode)
    {
    case BEEP_DO_NOTHING:
        {
        } break;

    default:
    case BEEP_IDLE:
        {
            BEEP_OFF;
            s_BeepMode = BEEP_DO_NOTHING;
        } break;

    case MOUSE_ERROR:
        {
            switch (s_BeepProcess)
            {
            default:
            case 0:
                {
                    if (s_BeepCntDown == 0)
                    {
                        BEEP_ON;
                        s_BeepCntDown = 200;
                        s_BeepProcess = 1;
                    }
                    --s_BeepCntDown;
                } break;
            case 1:
                {
                    if (s_BeepCntDown == 0)
                    {
                        BEEP_OFF;
                        s_BeepCntDown = 300;
                        s_BeepProcess = 2;
                    }
                    --s_BeepCntDown;
                } break;
            case 2:
                {
                    if (s_BeepCntDown == 0)
                    {
                        BEEP_ON;
                        s_BeepCntDown = 200;
                        s_BeepProcess = 3;
                    }
                    --s_BeepCntDown;
                } break;
            case 3:
                {
                    if (s_BeepCntDown == 0)
                    {
                        BEEP_OFF;
                        s_BeepCntDown = 1000;
                        s_BeepProcess = 0;
                    }
                    --s_BeepCntDown;
                } break;
            }
        } break;
    }
}

u8 GetSWStatus(void)
{
    u8 rc = s_OnOffStatus;
    s_OnOffStatus &= ~(ON_STATUS | OFF_STATUS);
    return (rc);
}

void SetOnStatus(void)
{
    s_OnOffStatus |= ON_STATUS;
    //Led_InvLed();
}

void SetOffStatus(void)
{
    s_OnOffStatus |= OFF_STATUS;
    //Led_InvLed();
}

void SWUpdateStatus(void)
{
    if( 0 == (SW_ON_PORT->IDR & SW_ON_PINS) )
    {
        if ( FALSE == OnBitOld )
        {
            if( SW_ACTIVE_DEBOUCE <= s_OnBitCnt )
            {
                SetOnStatus();
                OnBitOld = TRUE;
                s_OnBitCnt = 0;
            }
        }
        else
        {
            s_OnBitCnt = 0;
        }
    }
    else
    {
        if( TRUE == OnBitOld )
        {
            if( SW_DEBOUCE <= s_OnBitCnt )
            {
                OnBitOld = FALSE;
                s_OnBitCnt = 0;
            }
        }
        else
        {
            s_OnBitCnt = 0; 
        }
    }
    
    if( 0 == (SW_OFF_PORT->IDR & SW_OFF_PINS) )
    {
        if ( FALSE == OffBitOld )
        {
            if( SW_ACTIVE_DEBOUCE <= s_OffBitCnt )
            {
                SetOffStatus();
                OffBitOld = TRUE;
                s_OffBitCnt = 0;
            }
        }
        else
        {
            s_OffBitCnt = 0;
        }
    }
    else
    {
        if( TRUE == OffBitOld )
        {
            if( SW_DEBOUCE <= s_OffBitCnt )
            {
                OffBitOld = FALSE;
                s_OffBitCnt = 0;
            }
        }
        else
        {
            s_OffBitCnt = 0; 
        }
    }
    
    // if( 0 == (SW_OFF_PORT->IDR & SW_OFF_PINS) )
    // {
        // if ( FALSE == OffBitOld )
        // {
            // SetOffStatus();
        // }
        // OffBitOld = TRUE;
        // s_OffBitCnt = 0;
    // }
    // else
    // {
        // if( TRUE == OffBitOld )
        // {
            // if( SW_DEBOUCE <= s_OffBitCnt )
            // {
                // OffBitOld = FALSE;
            // }
        // }
    // }
}

void Led_RunOne(void)
{
    static u8 s_Cnt = 0;
    if (TRUE == s_Led_IntFlag)
    {
        s_Led_IntFlag = FALSE;
        
        if (5 <= ++s_Cnt)
        {
            s_Cnt = 0;
            Led_InvLed();
        }
    }
    
    SWUpdateStatus();
}
